#ifndef PARTURDF_H
#define PARTURDF_H


#include <string>
#include <list>
#include <vector>
#include <map>
#include <fstream>
#include <nlohmann/json.hpp>
#include <stdexcept>
#include <iostream>


// 定义一个函数，将 std::string 转换为 nlohmann::json
static nlohmann::json stringToJson(const std::string& filePath) {
    try {
        std::ifstream file(filePath);

        if (!file.is_open()) {
            throw std::runtime_error("无法打开文件: " + filePath);
        }

        nlohmann::json j;
        file >> j;
        file.close();
        // 解析字符串为 JSON 对象
        // nlohmann::json j = nlohmann::json::parse(jsonString);
        return j;
    } catch (const nlohmann::json::parse_error& e) {
        // 捕获并处理 JSON 解析错误
        std::cerr << "JSON解析错误: " << filePath << "\t" << e.what() << std::endl;
        throw; // 重新抛出异常给调用者
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        std::cerr << "发生错误: " << e.what() << std::endl;
        throw; // 重新抛出异常给调用者
    }
}

typedef std::vector<std::string> URDFLinks;

class WRLJson  /** 胡博Json **/
{
public:
    std::string wrl_name;
    std::string dir_path; /**  **/

    int wrlid;

    int partCount;
    int workstation{1};

    /** parts **/
    std::map<int,std::string>  stls;
    std::map<int,std::string>  urdfs;
    std::map<int,std::string>  part_name;

    bool operator<(const WRLJson& other) const {
        return wrlid < other.wrlid;
    }

    // 序列化为 JSON
    friend void to_json(nlohmann::json& j, const WRLJson& wrl) {
        j = nlohmann::json{
            {"wrl_name", wrl.wrl_name},
            {"dir_path", wrl.dir_path},
            {"wrlid", wrl.wrlid},
            {"partCount", wrl.partCount},
            {"workstation", wrl.workstation},
            {"stls", wrl.stls},
            {"urdfs", wrl.urdfs},
            {"part_name", wrl.part_name}
        };
    }

    // 反序列化从 JSON
    friend void from_json(const nlohmann::json& j, WRLJson& wrl) {
        j.at("wrl_name").get_to(wrl.wrl_name);
        j.at("dir_path").get_to(wrl.dir_path);
        j.at("wrlid").get_to(wrl.wrlid);
        j.at("partCount").get_to(wrl.partCount);
        j.at("workstation").get_to(wrl.workstation);
        // j.at("stls").get_to(wrl.stls);
        j.at("urdfs").get_to(wrl.urdfs);
        //j.at("part_name").get_to(wrl.part_name);
    }

};

typedef std::map<int, WRLJson> WRLJsonMap;

typedef std::vector<WRLJson> WRLJsonList;

// 从JSON文件加载WRLJsonMap
static WRLJsonMap loadWRLJsonMapFromFile(const std::string& filePath) {
    WRLJsonMap wrlJsonMap;
    std::ifstream file(filePath);

    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + filePath);
    }

    try {
        nlohmann::json j;
        file >> j; // 将文件内容解析为json对象

        for (const auto& [keyStr, value] : j.items()) { // 使用结构化绑定
            try {
                int key = std::stoi(keyStr); // 将字符串键转换为整数
                WRLJson wrl;
                from_json(value, wrl); // 使用之前定义的from_json方法反序列化
                wrlJsonMap[key] = wrl;
            } catch (const std::invalid_argument& e) {
                // 如果转换失败（例如，键不是有效的整数）
                std::cerr << "无效的键格式: " << keyStr << "\n";
                continue; // 跳过这个条目
            } catch (const std::out_of_range& e) {
                // 如果数字超出int范围
                std::cerr << "键超出范围: " << keyStr << "\n";
                continue; // 跳过这个条目
            }
        }
    } catch (const nlohmann::json::exception& e) {
        // 捕获并处理JSON解析异常
        throw std::runtime_error("JSON解析错误: " + std::string(e.what()));
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        throw std::runtime_error("读取文件时发生错误: " + std::string(e.what()));
    }

    file.close();
    return wrlJsonMap;
}



// 保存 WRLJsonMap 到 JSON 文件
static void saveWRLJsonMapToFile(const WRLJsonMap& wrlJsonMap, const std::string& filePath) {
    nlohmann::json j;

    // 遍历 WRLJsonMap 并将其内容添加到 JSON 对象中
    for (const auto& [key, value] : wrlJsonMap) {
        j[std::to_string(key)] = value; // 使用字符串键存储，以确保兼容性
    }

    // 打开文件进行写入
    std::ofstream file(filePath);

    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + filePath);
    }

    try {
        // 将 JSON 写入文件
        file << j.dump(4); // 使用缩进使输出更易读（4个空格）
    } catch (const nlohmann::json::exception& e) {
        // 捕获并处理JSON序列化异常
        throw std::runtime_error("JSON序列化错误: " + std::string(e.what()));
    } catch (const std::exception& e) {
        // 捕获其他可能的异常
        throw std::runtime_error("写入文件时发生错误: " + std::string(e.what()));
    }

    file.close();
}

// 序列化函数：将 std::vector<std::string> 转换为 JSON 字符串
static std::string serializeVectorToJson(const std::vector<std::string>& vec) {
    // 将字符串向量转换为 JSON 数组
    nlohmann::json j_vec = vec;
    // 将 JSON 对象转换为字符串并返回
    return j_vec.dump(4);  // 使用缩进输出，4 表示缩进空格数
}

// 反序列化函数：从 JSON 字符串读取到 std::vector<std::string>
static std::vector<std::string> deserializeJsonToVector(const std::string& json_str) {
    // 解析 JSON 字符串
    nlohmann::json j_vec = nlohmann::json::parse(json_str);
    // 将 JSON 数组转换回 std::vector<std::string>
    return j_vec.get<std::vector<std::string>>();
}


#endif // PARTURDF_H
